﻿<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0046)http://www.vovisoft.com/dotNET/Bai14/Bai14.htm -->
<HTML><HEAD><TITLE>.NET Lesson 14</TITLE>
<META http-equiv=Content-Type content="text/html; charset=utf-8">
<META http-equiv=Content-Language content=vi>
<META content="MSHTML 6.00.2716.2200" name=GENERATOR>
<META content=FrontPage.Editor.Document name=ProgId>
<META 
content="Visual Basic, VB Programming in Vietnamese, Vovisoft, VB6, VB Tutorials, Learn Visual Basic, Internet, Unicode, Vietnamese VB tutorials, Database, Asp, Java, Javascript, VBscript, FrontPage 2000, XML, Ms Office 2000" 
name=keywords></HEAD>
<BODY leftMargin=0 topMargin=0 marginheight="0" marginwidth="0">
<CENTER><A href="http://www.vovisoft.com/"><IMG height=77 alt="Logo of Vovisoft" 
src="Bai 14_files/vs-logo4_10.gif" width=102 border=0> </A><FONT face=Tahoma>
<H2><FONT face=Tahoma color=#800000>Bài 14</FONT></H2>
<H2><FONT face=Tahoma color=#800000>DataGrid (phần II)</FONT></H2></CENTER>
<BLOCKQUOTE>
  <BLOCKQUOTE>
    <H3><FONT color=blue>Dùng Dataview để Filter và Sort</FONT></H3>Thường 
    thường, khi điều khiển trong thời gian thật (real-time control), là 
    Operator, ta muốn các alarms có ưu tiên cao và mới xãy ra nhất được hiển thị 
    trên hết. Đôi khi, ta chỉ muốn thấy các alarm priority 3 (ưu tiên cao nhất) 
    mà thôi. Để thực hiện các việc nầy, ta dùng <B>Dataview</B> 
    Object.<BR><BR>Thay vì dùng thẳng table <B>alarm</B> của DataSet 
    <B>alarmlist</B> làm <B>datasource</B> của DataGrid1, ta sẽ dùng một 
    DataView derived from (đến từ) table alarm. Ta có thể <B>Sort</B> (sắp theo 
    thứ tự) các alarms/records theo Priority hay áp dụng <B>Filter</B> (sàn lọc) 
    vào DataView để chỉ thấy những thứ gì mình muốn, thí dụ chỉ có alarms 
    priority 3 thôi.<BR><BR>Nên nhớ là nằm đàng sau vẫn là table alarm, nhưng 
    Dataview đóng vai trò cặp kiếng mát màu giúp cho ta thấy những thứ gì và 
    theo cách ta muốn. Mỗi khi ta thay một cặp kiếng, ta lại thấy những thứ 
    khác.<BR><BR>Dưới đây là Sub BtnLoadXMLData_Click được sửa lại một chút để 
    dùng DataView:<BR><BR>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT color=blue>Private</FONT> <FONT color=blue>Sub</FONT> BtnLoadXMLData_Click(<FONT color=blue>ByVal</FONT> sender <FONT color=blue>As</FONT> System.Object, <FONT color=blue>ByVal</FONT> e <FONT color=blue>As</FONT> System.EventArgs) _
                                                          <FONT color=blue>Handles</FONT> BtnLoadXMLData.Click 
   <FONT color=green>' Instantiate a DataSet type alarmlist</FONT>
   DS = <FONT color=blue>New</FONT> alarmlist() 
   <FONT color=green>' Load the XML data from file AlarmList.xml in the source code folder. Note that the program EXE resides</FONT>
   <FONT color=green>' in the bin subfolder</FONT>
   DS.ReadXml("../AlarmList.xml") 
   <FONT color=green>' Bind the Datagrid DataSource to this new DataSet table alarm</FONT>
   <FONT color=green>' DataGrid1.DataSource = DS.alarm</FONT>
   <FONT color=green>' Create a Dataview from DS</FONT>
   DV1 = <FONT color=blue>New</FONT> System.Data.DataView(DS.alarm) 
   <FONT color=green>' Sort alarms by priority, then datetime</FONT>
   <FONT color=green>' DESC stands for descending order,i.e. biggest on top</FONT>
   DV1.Sort = "priority DESC, datetime DESC" 
   <FONT color=green>' Bind the Datagrid DataSource to Dataview</FONT>
   DataGrid1.DataSource = DV1 
   AddCustomDataTableStyle() 
   <FONT color=green>' Display the number of alarms in each priority</FONT>
   DisplayTotal() 
<FONT color=blue>End</FONT> <FONT color=blue>Sub</FONT> 
</PRE></FONT></TD></TR></TBODY></TABLE><BR>Để ý Dataview object <B>DV1</B> 
    được derived từ <B>DS.alarm</B>. Sau đó ta Sort các alarms theo thứ tự ưu 
    tiên, rồi trong số những alarm có cùng priority ta lại Sort chúng theo 
    <B>datetime</B> (ở đây data type của datetime chỉ là string).<BR><BR>Ngoài 
    ra để đếm con số các alarms thuộc mỗi priority ta có thể dùng Dataview với 
    filter rồi xem <B>property Count</B> của nó như sau: 
    <BLOCKQUOTE>
      <TABLE bgColor=#f6f6f6>
        <TBODY>
        <TR>
          <TD><FONT size=3><PRE><FONT color=blue>Private</FONT> <FONT color=blue>Sub</FONT> DisplayTotal() 
   <FONT color=green>' Create a Dataview object from table DS.alarm</FONT>
   <FONT color=blue>Dim</FONT> DVP1 <FONT color=blue>As</FONT> <FONT color=blue>New</FONT> System.Data.DataView(DS.alarm) 
   <FONT color=green>' Apply filter</FONT>
   DVP1.RowFilter = "priority = 1" 
   <FONT color=green>' Display Count of records in this Dataview</FONT>
   NumPrio1.Text = "Prio1: " &amp; DVP1.Count.ToString 
   <FONT color=blue>Dim</FONT> DVP2 <FONT color=blue>As</FONT> <FONT color=blue>New</FONT> System.Data.DataView(DS.alarm) 
   DVP2.RowFilter = "priority = 2" 
   NumPrio2.Text = "Prio2: " &amp; DVP2.Count.ToString 
   <FONT color=blue>Dim</FONT> DVP3 <FONT color=blue>As</FONT> <FONT color=blue>New</FONT> System.Data.DataView(DS.alarm) 
   DVP3.RowFilter = "priority = 3" 
   NumPrio3.Text = "Prio3: " &amp; DVP3.Count.ToString 
   NumTotal.Text = "Total: " &amp; DS.alarm.Rows.Count.ToString 
   <FONT color=blue>Dim</FONT> bmb <FONT color=blue>As</FONT> BindingManagerBase = Me.BindingContext(DataGrid1.DataSource, DataGrid1.DataMember) 
   NumDisplayed.Text = "Displayed: " &amp; bmb.Count.ToString 
<FONT color=blue>End</FONT> <FONT color=blue>Sub</FONT> 
</PRE></FONT></TD></TR></TBODY></TABLE></BLOCKQUOTE>Chắc bạn đã để ý thấy 
    thay vì iterate qua mỗi record để đếm con số alarms thuộc priority 1,2 hay 
    3, ta đã dùng ba Dataviews để filter ra alarms thuộc ba priorities khác nhau 
    rồi lấy trị số Count của mỗi Dataview. Đây là lối lập trình dựa vào những gì 
    có sẵn càng nhiều càng tốt để tránh tạo ra bugs.<BR><BR>Ngoài ra, để đếm con 
    số hàng alarms được thật sự hiển thị bất cứ lúc nào ta dùng 
    <B>BindingManagerBase</B> object trong hai hàng code dưới đây:<BR><BR>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT color=blue>Dim</FONT> bmb <FONT color=blue>As</FONT> BindingManagerBase = Me.BindingContext(DataGrid1.DataSource, DataGrid1.DataMember) 
NumDisplayed.Text = "Displayed: " &amp; bmb.Count.ToString 
</PRE></FONT></TD></TR></TBODY></TABLE><BR>Ta đặt thêm ba buttons để filter 
    alarms với code sau đây: 
    <BLOCKQUOTE>
      <TABLE bgColor=#f6f6f6>
        <TBODY>
        <TR>
          <TD><FONT size=3><PRE><FONT color=blue>Private</FONT> <FONT color=blue>Sub</FONT> Btn1and2_Click(<FONT color=blue>ByVal</FONT> sender <FONT color=blue>As</FONT> System.Object, <FONT color=blue>ByVal</FONT> e <FONT color=blue>As</FONT> System.EventArgs) _ 
                                                                    <FONT color=blue>Handles</FONT> Btn1and2.Click 
   DV1.RowFilter = "priority &lt; 3" 
   <FONT color=blue>Dim</FONT> bmb <FONT color=blue>As</FONT> BindingManagerBase = Me.BindingContext(DataGrid1.DataSource, DataGrid1.DataMember) 
   NumDisplayed.Text = "Displayed: " &amp; bmb.Count.ToString 
<FONT color=blue>End</FONT> <FONT color=blue>Sub</FONT> 

<FONT color=blue>Private</FONT> <FONT color=blue>Sub</FONT> Btn1Only_Click(<FONT color=blue>ByVal</FONT> sender <FONT color=blue>As</FONT> System.Object, <FONT color=blue>ByVal</FONT> e <FONT color=blue>As</FONT> System.EventArgs) _
                                                                    <FONT color=blue>Handles</FONT> Btn1Only.Click 
   DV1.RowFilter = "priority = 1" 
   <FONT color=blue>Dim</FONT> bmb <FONT color=blue>As</FONT> BindingManagerBase = Me.BindingContext(DataGrid1.DataSource, DataGrid1.DataMember) 
   NumDisplayed.Text = "Displayed: " &amp; bmb.Count.ToString 
<FONT color=blue>End</FONT> <FONT color=blue>Sub</FONT> 

<FONT color=blue>Private</FONT> <FONT color=blue>Sub</FONT> BtnAllAlarms_Click(<FONT color=blue>ByVal</FONT> sender <FONT color=blue>As</FONT> System.Object, <FONT color=blue>ByVal</FONT> e <FONT color=blue>As</FONT> System.EventArgs) _
                                                                    <FONT color=blue>Handles</FONT> BtnAllAlarms.Click 
   DV1.RowFilter = "" 
   <FONT color=blue>Dim</FONT> bmb <FONT color=blue>As</FONT> BindingManagerBase = Me.BindingContext(DataGrid1.DataSource, DataGrid1.DataMember) 
   NumDisplayed.Text = "Displayed: " &amp; bmb.Count.ToString 
<FONT color=blue>End</FONT> <FONT color=blue>Sub</FONT> 
</PRE></FONT></TD></TR></TBODY></TABLE></BLOCKQUOTE>Bạn có thể chay chương 
    trình và bấm các nút vừa mới thêm vào để xem các alarms được filtered như 
    thế nào. 
    <BLOCKQUOTE><IMG height=240 src="Bai 14_files/Dataview.gif" 
    width=752></BLOCKQUOTE>
    <H3><FONT color=green>Làm việc với một Row trong DataGrid</FONT></H3>Khi một 
    alarm mới được báo cáo và hiển thị, hệ thống điều khiển real-time thường hay 
    phát ra những tiếng Beep nho nhỏ để nhắc Operator xử lý sự cố tạo ra alarm. 
    Việc đầu tiên Operator sẽ làm là <B>Acknowledge</B> (xác nhận là tôi biết 
    rồi, khổ lắm, nói mãi!) cái alarm bằng cách right click lên Row hiển thị 
    alarm rồi click menuCommand <B>Acknowledge</B> từ PopupMenu.<BR><BR>Khi bạn 
    đã Acknowledge một alarm rồi thì cái ACKN checkbox sẽ được đánh dấu và nếu 
    hệ thống không còn alarm nào chưa được acknowledged thì nó sẽ ngừng Beep. 
    Ngoài ra, có khi vì bạn biết là lý do gây ra một alarm nào đó không quan 
    trọng (thí dụ nhân viên kỹ thuật đang sửa và thử cái sensor của alarm ấy) và 
    bạn không muốn alarm ấy được báo cáo trong tương lai, bạn có thể 
    <B>Isolate</B> (cô lập hóa) nó. Khi nào muốn cho nó hoạt động bình thường 
    trở lại, bạn sẽ <B>Enable</B> (tác động) nó.<BR><BR>Bây giờ bạn hãy đặt một 
    ContextMenu control vào form và Edit cho nó ba menuCommands tên 
    <B>mnuAckn(Acknowledge)</B>, <B>mnuIsolate(Isolate)</B> và 
    <B>mnuEnable(Enable)</B> như trong hình dưới đây: 
    <BLOCKQUOTE><IMG height=368 src="Bai 14_files/PopUpMenu.gif" 
    width=804></BLOCKQUOTE>Mỗi khi user right click lên một hàng alarm, 
    ContextMenu1 sẽ hiển thị chỉ những menuCommands thích hợp với tình huống. 
    Tức là nếu alarm chưa được acknowledged thì mới có menuCommand Acknowledge, 
    khi alarm chưa bị isolated thì mới có menuCommand Isolate, nếu đã bị 
    isolated rồi thì chỉ có MenuCommand Enable.<BR><BR>Bình thường, nếu bạn 
    click lên một checkbox còn trống trong DataGrid1, checkbox ấy sẽ được đánh 
    dấu. Nhưng trong chương trình của chúng ta tại đây ta không muốn cho user 
    làm việc ấy mà phải Acknowlege, Isolate hay Enable bằng PopupMenu. Do đó bạn 
    hãy cho <B>property ReadOnly</B> của DataGrid1 bằng True.<BR><BR>Lúc chương 
    trình nhận được Event MouseDown từ DataGrid1 ta sẽ tìm cách xác định lúc bấy 
    giờ Mouse đang nằm trên alarm line nào bằng cách chạy Method <B>HitTest</B> 
    của DataGrid1. Khi DataGrid1 HitTest vị trí của Mouse với instruction 
    <B>myGrid.HitTest(e.X, e.Y)</B>, nó sẽ cho ta một Object <B>HitTestInfo</B>. 
    Property <B>Row</B> của HitTestInfo là hàng thứ mấy trong DataGrid1. 
    <BR><BR>Để lấy ra đúng <B>DataRowView</B> nào đang hiển thị ở 
    <B>HitTestInfo.Row</B> ấy ta phải dựa vào <B>BindingManagerBase</B>. Cái 
    DataRowView mà ta đang tìm chính là DataRowView của BindingManagerBase với 
    <B>position</B> bằng HitTestInfo.Row ấy.<BR><BR>Trong chương trình nầy, ta 
    sẽ chứa DataRowView ấy trong variable <B>drv</B>. Dưới đây là code để xử lý 
    Event MouseDown của DataGrid1, để ý là ta hiển thị bên dưới cái 
    <B>description</B> của alarm được clicked bằng statement <B>Label1.Text = 
    drv("description")</B> để cho user một feedback:<BR>
    <BLOCKQUOTE>
      <TABLE bgColor=#f6f6f6>
        <TBODY>
        <TR>
          <TD><FONT size=3><PRE><FONT color=green>' Variable used to store selected DataRowView</FONT>
<FONT color=blue>Dim</FONT> drv <FONT color=blue>As</FONT> DataRowView 
<FONT color=blue>Private</FONT> <FONT color=blue>Sub</FONT> DataGrid1_MouseDown(<FONT color=blue>ByVal</FONT> sender <FONT color=blue>As</FONT> Object, <FONT color=blue>ByVal</FONT> e <FONT color=blue>As</FONT> System.Windows.Forms.MouseEventArgs) _
                                                                       <FONT color=blue>Handles</FONT> DataGrid1.MouseDown 
   <FONT color=green>' Only proceed when Mouse Right Button was clicked</FONT>
   <FONT color=blue>If</FONT> e.Button &lt;&gt; MouseButtons.Right <FONT color=blue>Then</FONT> <FONT color=blue>Exit</FONT> <FONT color=blue>Sub</FONT> 
   <FONT color=green>' Typecast sender to DataGrid data type. myGrid is actually DataGrid1</FONT>
   <FONT color=blue>Dim</FONT> myGrid <FONT color=blue>As</FONT> DataGrid = CType(sender, DataGrid) 
   <FONT color=green>' Declare a HitTestInfo variable</FONT>
   <FONT color=blue>Dim</FONT> hti <FONT color=blue>As</FONT> DataGrid.HitTestInfo 
   <FONT color=green>' Obtain the info about Mouse location</FONT>
   hti = myGrid.HitTest(e.X, e.Y) 
   <FONT color=green>' Only proceed when a Cell was hit</FONT>
   <FONT color=blue>If</FONT> hti.Type = DataGrid.HitTestType.Cell <FONT color=blue>Then</FONT> 
      <FONT color=blue>Try</FONT> 
         <FONT color=green>' Obtain BindingManagerBase of DataGrid1</FONT>
         <FONT color=blue>Dim</FONT> bmb <FONT color=blue>As</FONT> BindingManagerBase = Me.BindingContext(myGrid.DataSource, myGrid.DataMember) 
         <FONT color=green>' Position at DataRowView corresponding to the physical row that was hit</FONT>
         bmb.Position = hti.Row 
         <FONT color=green>' Store the found DataRowView in temporary variable drv</FONT>
         drv = bmb.Current 
         <FONT color=green>' Display description of the alarm line as a feedback</FONT>
         Label1.Text = drv("description") 
         <FONT color=blue>If</FONT> <FONT color=blue>Not</FONT> (drv Is Nothing) <FONT color=blue>Then</FONT> 
            <FONT color=green>' Only display the MenuCommands that are appropriate to this context</FONT>
            <FONT color=blue>Dim</FONT> ctx <FONT color=blue>As</FONT> DataRow = drv.Row 
            <FONT color=blue>If</FONT> <FONT color=blue>Not</FONT> (ctx Is Nothing) <FONT color=blue>Then</FONT> 
               <FONT color=blue>If</FONT> drv("ackn") = <FONT color=blue>True</FONT> <FONT color=blue>Then</FONT> 
                  mnuAckn.Visible = <FONT color=blue>False</FONT> 
               <FONT color=blue>Else</FONT> 
                  <FONT color=green>' Only display menuCommand Ackn when alarm is not yet acknowledged</FONT>
                  mnuAckn.Visible = <FONT color=blue>True</FONT> 
               <FONT color=blue>End</FONT> <FONT color=blue>If</FONT> 
               <FONT color=blue>If</FONT> drv("isolate") = <FONT color=blue>True</FONT> <FONT color=blue>Then</FONT> 
                  <FONT color=green>' If alarm is already isolated then only display MenuCommand Enable</FONT>
                  mnuIsolate.Visible = <FONT color=blue>False</FONT> 
                  mnuEnable.Visible = <FONT color=blue>True</FONT> 
               <FONT color=blue>Else</FONT> 
                  mnuIsolate.Visible = <FONT color=blue>True</FONT> 
                  mnuEnable.Visible = <FONT color=blue>False</FONT> 
               <FONT color=blue>End</FONT> <FONT color=blue>If</FONT> 
               <FONT color=green>' Popup context menu</FONT>
               ContextMenu1.Show(myGrid, <FONT color=blue>New</FONT> Point(e.X, e.Y)) 
            <FONT color=blue>End</FONT> <FONT color=blue>If</FONT> 
         <FONT color=blue>End</FONT> <FONT color=blue>If</FONT> 
      <FONT color=blue>Catch</FONT> ex <FONT color=blue>As</FONT> Exception 
         MessageBox.Show(ex.ToString()) 
      <FONT color=blue>End</FONT> <FONT color=blue>Try</FONT> 
   <FONT color=blue>End</FONT> <FONT color=blue>If</FONT> 
<FONT color=blue>End</FONT> <FONT color=blue>Sub</FONT> 
</PRE></FONT></TD></TR></TBODY></TABLE></BLOCKQUOTE>Khi User click một trong 
    các Popup menu commands ta thay đổi các boolean value Ackn hay Isolate và 
    viết xuống AlarmList.xml data file như sau:<BR><BR>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT color=blue>Private</FONT> <FONT color=blue>Sub</FONT> mnuAckn_Click(<FONT color=blue>ByVal</FONT> sender <FONT color=blue>As</FONT> System.Object, <FONT color=blue>ByVal</FONT> e <FONT color=blue>As</FONT> System.EventArgs) <FONT color=blue>Handles</FONT> mnuAckn.Click 
   <FONT color=blue>If</FONT> <FONT color=blue>Not</FONT> drv Is <FONT color=blue>Nothing</FONT> <FONT color=blue>Then</FONT> 
      drv("ackn") = <FONT color=blue>True</FONT> 
      UpdatePoint() 
   <FONT color=blue>End</FONT> <FONT color=blue>If</FONT> 
<FONT color=blue>End</FONT> <FONT color=blue>Sub</FONT> 
<FONT color=blue>Private</FONT> <FONT color=blue>Sub</FONT> mnuIsolate_Click(<FONT color=blue>ByVal</FONT> sender <FONT color=blue>As</FONT> System.Object, <FONT color=blue>ByVal</FONT> e <FONT color=blue>As</FONT> System.EventArgs) <FONT color=blue>Handles</FONT> mnuIsolate.Click 
   <FONT color=blue>If</FONT> <FONT color=blue>Not</FONT> drv Is <FONT color=blue>Nothing</FONT> <FONT color=blue>Then</FONT> 
      drv("isolate") = <FONT color=blue>True</FONT> 
      UpdatePoint() 
   <FONT color=blue>End</FONT> <FONT color=blue>If</FONT> 
<FONT color=blue>End</FONT> <FONT color=blue>Sub</FONT> 
<FONT color=blue>Private</FONT> <FONT color=blue>Sub</FONT> mnuEnable_Click(<FONT color=blue>ByVal</FONT> sender <FONT color=blue>As</FONT> System.Object, <FONT color=blue>ByVal</FONT> e <FONT color=blue>As</FONT> System.EventArgs) <FONT color=blue>Handles</FONT> mnuEnable.Click 
   <FONT color=blue>If</FONT> <FONT color=blue>Not</FONT> drv Is <FONT color=blue>Nothing</FONT> <FONT color=blue>Then</FONT> 
      drv("isolate") = <FONT color=blue>False</FONT> 
      UpdatePoint() 
   <FONT color=blue>End</FONT> <FONT color=blue>If</FONT> 
<FONT color=blue>End</FONT> <FONT color=blue>Sub</FONT> 
<FONT color=blue>Private</FONT> <FONT color=blue>Sub</FONT> UpdatePoint() 
   <FONT color=green>' Accept the changes in DataSet</FONT>
   DS.AcceptChanges() 
   <FONT color=green>' Write updated data to XML file to persist the information</FONT>
   DS.WriteXml("..\AlarmList.xml") 
<FONT color=blue>End</FONT> <FONT color=blue>Sub</FONT> 
</PRE></FONT></TD></TR></TBODY></TABLE><BR>Khi khởi động chương trình và 
    right click lên alarm point 402-2-9 để Acknowledge nó bạn sẽ thấy như sau: 
    <BLOCKQUOTE><IMG height=240 src="Bai 14_files/Ackn.gif" 
    width=752></BLOCKQUOTE><BR><BR>Bạn có thể <A 
    href="http://www.vovisoft.com/dotNET/Bai14/AlarmList.zip">tải về chương 
    trình AlarmList nầy</A> tại đây. 
    <H3><FONT color=green>Edit một XML Schema</FONT></H3>Trong chương trình mới 
    nầy ta sẽ có một áp dụng khác cho DataGrid. Ta muốn tạo ra một DataForm để 
    Edit chi tiết của các Operators, những người được phép dùng hệ thống điều 
    khiển Real-time On-line để Acknowledge alarm, mở, tắt các quạt, máy 
    bơm,.v.v..<BR><BR>DataForm nầy sẽ có một DataGrid nằm bên dưới cho ta một 
    hình spreadsheet của tất cả các Operator records, và ta có thể chọn làm việc 
    với record nào bằng cách click bên trái của record ấy trong 
    spreadsheet.<BR><BR>Trước hết bạn hãy khởi động một project mới tên 
    Operators. Kế đó dùng IDE MenuCommand <B>Project | Add New Item</B> để thêm 
    một XML Schema bằng cách click lên icon <B>XML Schema</B>. Chỗ Name 
    <B>XMLSchema1.xsd</B> hãy sửa nó thành <B>operatorlist.xsd</B> như trong 
    hình dưới đây:<BR>
    <BLOCKQUOTE><IMG height=397 src="Bai 14_files/addschema.gif" 
    width=530></BLOCKQUOTE>Để Edit cái schema mới nầy, bạn hãy doubleclick lên 
    tên operatorlist.xsd trong Solution Explorer. Một khung vàng nhạt còn trống 
    sẽ hiện ra ở giữa. Bạn hãy drag icon <FONT color=blue><B>E</B></FONT> 
    <B>Element</B> từ <B>XML Schema Toolbox</B> (nằm bên trái ) vào khung vàng 
    nhạt. Hãy click lên chữ Element1 (nằm bên phải chữ <FONT 
    color=blue><B>E</B></FONT>) trong hình mới tạo ra và sửa nó thành 
    <B>operator</B> như trong hình dưới đây: 
    <BLOCKQUOTE><IMG height=284 src="Bai 14_files/elementOperator.gif" 
      width=764></BLOCKQUOTE>Kế đó drag icon <FONT color=blue><B>A</B></FONT> 
    <B>Attribute</B> từ XML Schema Toolbox vào drop nó ngay trên hàng nằm dưới 
    Element operator. Sửa tên Attribute đó thành <B>operatorid</B>. Click bên 
    phải chữ <B>string</B> của operatorid để chọn datatype <B>integer</B> từ 
    ComboBox. Lập lại cùng những thao tác ấy cho Attributes <B>username, 
    password</B> và <B>level</B>. Click bên phải chữ <B>string</B> của level để 
    chọn datatype <B>integer</B> từ ComboBox.<BR><BR>Hể trị số level của một 
    operator càng lớn thì operator ấy càng có quyền để làm nhiều chuyện. 
    <B>MasterUser</B> là người có level cao nhất. Mỗi command trong hệ thống 
    điều khiển Real-time được cho một level mà user phải có một level với trị số 
    ít nhất là bằng nó thì mới dùng command ấy được. Thí dụ Command Modify 
    Username/Password/Level có level bằng 5 thì chỉ có MasterUser với level bằng 
    5 mới dùng nó được.<BR><BR>Đến đây ta đã định nghĩa xong các Attributes của 
    một Element operator mà ta sẽ dùng làm record trong Table operator trong cơ 
    sỡ dữ liệu XML. Để có một XML hợp lệ ta cần phải gói các Element operator 
    vào trong một Element gốc (root) mà ta sẽ gọi nó là 
    <B>operatorlist</B>.<BR><BR>Bạn hãy drag icon <FONT 
    color=blue><B>E</B></FONT> <B>Element</B> từ XML Schema Toolbox vào khung 
    vàng nhạt và sửa tên của Element đó thành <B>operatorlist</B>. Kế đó nắm góc 
    trái trên (top left) của hình Element oparator và drag drop nó vào ngay hàng 
    dưới chữ operatorlist của Element operatorlist. Bạn sẽ thấy hình dưới đây: 
    <BLOCKQUOTE><IMG height=373 src="Bai 14_files/operatorlist.gif" 
    width=761></BLOCKQUOTE>Nếu bây giờ bạn click Tab <B>XML</B> phía dưới của 
    khung vàng nhạt bạn sẽ thấy mã nguồn XML của Schema operatorlist.xsd như 
    sau:<BR><BR><IMG height=422 src="Bai 14_files/schemaXML.gif" 
    width=978><BR><BR>Mã nguồn XML của Schema operatorlist.xsd cho thấy Element 
    <B>operatorlist</B> là Element gốc (root) còn gọi là <B>DocumentElement</B> 
    của XML nầy. Bên trong Element <B>operatorlist</B> có Element 
    <B>operator</B>. Mỗi Element <B>operator</B> có những Attributes là 
    <B>operatorid, username, password</B> và <B>level</B>. Để ý datatype của 
    Attributes <B>operatorid</B> và <B>level</B> là <B>integer</B>.<BR><BR>Trở 
    lại hình của Schema bằng cách click Tab <B>Schema</B> phía dưới, ta thấy 
    hàng đầu tiên của mỗi khung chữ nhật chứa tên của Element chủ của khung ấy. 
    Từ hàng thứ nhì trở xuống là định nghĩa những gì thuộc về Element 
    ấy.<BR><BR><I>(còn tiếp)</I><BR><BR>
    <BLOCKQUOTE><A href="http://www.vovisoft.com/"><IMG height=40 
      src="Bai 14_files/homejump.gif" width=40><A>&nbsp;&nbsp;<A 
      href="http://www.vovisoft.com/dotNET/default.asp">Học Microsoft 
      .NET</A><BR><BR></BLOCKQUOTE></FONT><!-- Start of bottom bar for copyright notice etc -->
    <TABLE class=clsNavLinks id=tblFooterLinks cellSpacing=0 cellPadding=0 
    width="100%" border=0>
      <TBODY>
      <TR>
        <TD class=clsRaised width=785 bgColor=#6699cc colSpan=5>
          <P align=center><FONT face=Tahoma color=#ffffff size=1>Vovisoft © 
          2000. All rights reserved.</FONT></P></TD></TR>
      <TR>
        <TD width=256>
          <P align=center><FONT face=Tahoma size=1>&nbsp;&nbsp; Last Updated: <!--webbot 
      bot="Timestamp" S-Type="REGENERATED" S-Format="%d %b %Y" startspan -->11 
          Apr 2002<!--webbot 
      bot="Timestamp" endspan i-checksum="15027" --> </FONT></P></TD>
        <TD width=181><FONT face=Tahoma size=1>&nbsp;</FONT></TD>
        <TD width=258>
          <P align=center><FONT face=Tahoma size=1><A 
          href="mailto:dixon@vovisoft.com">Webmaster</A></FONT></P></TD></TR></TBODY></TABLE><BR></BLOCKQUOTE></BLOCKQUOTE></BODY></HTML>
